
#ifndef _TTY_CPP_
#define _TTY_CPP_

#include "tty.hpp"

CALLCONV TTY::TTY(){
	currentRow = currentColumn = 0;
}
	
CALLCONV bool TTY::printString(char* str, Parameters p){
	if(str == (char*)0 || p.row >= ROWS || p.column >= COLUMNS) return false;
	
	char* buffer = textBuffer + (unsigned)p.row * (unsigned)COLUMNS * 2 + (unsigned)p.column;
	currentRow = p.row; currentColumn = p.column;
	
	while(*str != p.endChar){
		if(*str == 8){	// backspace '\b'
			if(currentColumn == 0){
				if(currentRow == 0) return false;
				currentRow--;
				currentColumn = COLUMNS - 1;
			}else currentColumn--;
			buffer -= 2;
		}else if(*str == 9){	// tab '\t'
			register UINT8 spaceNum = 8 - (currentColumn & 7);
			if(currentColumn + spaceNum >= COLUMNS){
				if(currentRow + 1 >= ROWS) return false;
				currentColumn = 0;
				currentRow++;
			}else currentColumn += spaceNum;
			while(spaceNum > 0){
				*buffer++ = ' ';
				*buffer++ = p.color;
				spaceNum--;
			}
		}else if(*str == 10){	// '\n'
			buffer -= (unsigned)currentColumn * 2;
			currentColumn = 0;
		}else if(*str == 13){	// '\r'
			if(currentRow + 1 >= ROWS) return false;
			currentRow++;
			buffer += (unsigned)COLUMNS * 2;
		}else{
			if(currentColumn + 1 >= COLUMNS){
				if(currentRow + 1 >= ROWS) return false;
				currentRow++;
				currentColumn = 0;
			}else currentColumn++;
			*buffer++ = *str;
			*buffer++ = p.color;
		}
		str++;
	}
	return true;
}

char* const TTY::textBuffer = (char*)0xB8000;
const UINT8 TTY::COLUMNS = 80, TTY::ROWS = 25, TTY::TAB_LENGTH = 8;

#endif // _TTY_CPP_
